[core] Search primary-key vector buckets and files concurrently#556
Conversation
eb6bc77 to
f27a56d
Compare
f27a56d to
2836ae1
Compare
Add a global-index.thread-num option (default 32, rejected when non-positive) and thread its value as a concurrency limit through the primary-key vector search. The per-bucket loop in the orchestrator and the exact-fallback per-file loop in the bucket search now fan out with buffer_unordered up to that limit; a limit of 1 takes a plain sequential loop so file and bucket visit order stay deterministic. Results are accumulated by fixed query and split index and merged through the existing order-independent bounded heaps and global top-k, so the output does not depend on completion order. The ANN segment scan stays sequential because it is synchronous CPU work.
2836ae1 to
913b162
Compare
|
|
global-index.thread-num was applied independently at both fan-out levels: up to N bucket futures, and each bucket started up to N exact-file futures, so a single search could run up to N*N concurrent exact-file searches (and concurrent queries multiplied it further). Mirror Java's single shared GlobalIndexReadThreadPool by threading one Arc<Semaphore> of N permits through the whole search and acquiring it only around leaf exact-file I/O. Bucket orchestration never holds a permit, so it cannot starve leaf work (the async analogue of Java's "start from the caller" note in PrimaryKeyVectorRead.searchBuckets). Total in-flight exact-file searches are now capped at N overall rather than per bucket; the concurrency == 1 path stays strictly sequential. Add search_candidates_peak_concurrency_capped_across_buckets: 2 buckets x 2 files at concurrency 2 must observe peak in-flight <= N (was 4).
|
Thanks @JingsongLi, you're exactly right — the limit was applied independently at each level, so a single search could reach N×N concurrent exact-file reads (and concurrent queries multiplied it further). Fixed in 5293431. Instead of two independent I also added |
Purpose
Part of #514, and the last of three PRs split out of the original combined change on the primary-key vector
execute_readpath (after #559 streaming exact fallback and #560 batch multi-query, both now onmain). This PR adds intra-search parallelism: a configurable concurrency limit fans the per-bucket and per-exact-file searches out, without changing results.Brief change log
perf(table): aglobal-index.thread-numoption (default 32, rejected when non-positive) threads a concurrency limit through the search. The per-bucket loop (orchestrator) and per-exact-file loop (bucket search) fan out withbuffer_unorderedup to that limit; a limit of 1 takes a plain sequential loop so visit order stays deterministic. Results are accumulated by fixed query and split index and merged through the existing order-independent bounded heaps and global top-k, so output does not depend on completion order. The ANN segment scan stays sequential (synchronous CPU work).refactor(table): the exclusion predicate threaded through the search (residual filter ∩ deletion vectors) is markedSend + Syncso the search future isSendand can run on a multi-threaded runtime.Tests
global-index.thread-numdefault/explicit/non-positive.cargo test -p paimon --libgreen (1793 passed);cargo clippy -p paimon --lib --testsandcargo fmt --checkclean.API and Format
No on-disk format change, no new result columns. The concurrency limit defaults to a value that does not change results, only scheduling. New public surface: the
global-index.thread-numoption (matches Java Paimon's option name, semantics, and default of 32).Documentation
Code comments only; no user-facing docs change.